using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using ShouldIt.Core;
using Xunit;

namespace ShouldIt.Xunit
{
    [Export(typeof(IAssertProvider))]
    public class AssertProvider : IAssertProvider
    {
        public void AreEqual(object expected, object actual)
        {
            Assert.Equal(expected, actual);
        }

        public void AreNotEqual(object expected, object actual)
        {
            Assert.NotEqual(expected, actual);
        }

        public void IsNotNull(object obj)
        {
            Assert.NotNull(obj);
        }

        public void IsNull(object value)
        {
            Assert.Null(value);
        }

        public void IsFalse(bool value)
        {
            Assert.False(value);   
        }

        public void IsTrue(bool value)
        {
            Assert.True(value);   
        }

        public void Fail(string messageFormat, params object[] args)
        {
            //TODO: This hack is recommened in xUnit docs to make up for lack of Assert.Fail
            Assert.True(false, args == null ? messageFormat : string.Format(messageFormat, args));
        }

        public void Contains<T>(T item, IEnumerable<T> enumerable)
        {
            Assert.Contains(item, enumerable);
        }

        public void NotContains<T>(T item, IEnumerable<T> enumerable)
        {
            Assert.DoesNotContain(item, enumerable);
        }

        public void Greater(int left, int right)
        {
            Assert.True(left > right);
        }

        public void GreaterOrEqual(int left, int right)
        {
            Assert.True(left >= right);
        }

        public void AreSame(object expected, object actual)
        {
            Assert.Same(expected, actual);
        }

        public void AreNotSame(object unExpected, object actual)
        {
            Assert.NotSame(unExpected, actual);
        }

        public void IsSubstringOf(string actual, string expectedSubstring)
        {
            Assert.Contains(expectedSubstring, actual);
        }

        public void IsInstanceOfType(object actual, Type expectedType)
        {
            Assert.IsType(expectedType, actual);
        }

        public void IsNotInstanceOfType(object actual, Type expectedType)
        {
            Assert.IsNotType(expectedType, actual);
        }
    }
}